package geom;
import geom.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ListIterator;

import processing.core.PApplet;

public class Line {
	public static float DEFAULT_FIT = 1.5f;
	public static float MAX_LENGTH = 100;
	private ArrayList<Vector> points;
	private ArrayList<Segment> segments;
	private Object parent;
	private boolean currentlyVisible = true;
	private Segment lastSegment;
	PApplet pa;
	
	
	
	
	public Line(PApplet pa){
		setPoints(new ArrayList<Vector>());
		setSegments(new ArrayList<Segment>());
		setLastSegment(null);
		this.pa = pa;
	}
	public Line(PApplet pa, Object parent){
		this(pa);
		this.setParent(parent);
	}
	public void addPoint(Vector v){
		addPoint(v, false);
	}
	public void addPoint(Vector v, boolean toggle){
		getPoints().add(v);
		//PApplet.println("line size" + getPoints().size());
		if(getPoints().size() <= 1) return;
		
		if(getLastSegment() == null && getPoints().size() > 1){
			setLastSegment(new Segment(this, getPoints().size()-2, getPoints().size()-1, currentlyVisible));
			
		} 
		
		while(getPoints().size() > getLastSegment().end + 1){
			
			getLastSegment().extend(1);
			int fit = getLastSegment().fits(DEFAULT_FIT);
			if(fit != -1){
				getLastSegment().trim(fit);
				getSegments().add(getLastSegment());
				setLastSegment(new Segment(this, fit, fit+1, currentlyVisible));
			}
		}
	}
	
	public void draw(){
		pa.noFill();
		pa.stroke(60, 70, 230);
		Iterator<Vector> it = getPoints().iterator();
		while(it.hasNext()){
			Vector p = it.next();
			pa.ellipse(p.x, p.y, 1, 1);
		}
		pa.stroke(220, 70, 100);
		Iterator<Segment> its = getSegments().iterator();
		while(its.hasNext()){
			its.next().draw();
		}
		if(getLastSegment() !=  null) getLastSegment().draw();
	}
	public void setSegments(ArrayList<Segment> segments) {
		this.segments = segments;
	}
	public ArrayList<Segment> getSegments() {
		return segments;
	}
	public void setPoints(ArrayList<Vector> points) {
		this.points = points;
	}
	public ArrayList<Vector> getPoints() {
		return points;
	}
	public void setParent(Object parent) {
		this.parent = parent;
	}
	public Object getParent() {
		return parent;
	}

	public int size(){
		return points.size();
	}
	public float length(){
		Iterator<Segment> sit = segments.iterator();
		float l = 0;
		while(sit.hasNext()){
			l += sit.next().length();
		}
		return l;
	}
	
	
	
	public Vector posAt(float l){
		
		//PApplet.println("lengthpos: " + l);
		if(segments.size() < 1) return null; 
		ListIterator<Segment> sit = segments.listIterator();
		float cl = 0;
		while(sit.hasNext() && cl < l){
			cl += sit.next().length();
		}
		Segment s = sit.previous();
		float pos = Math.min(l, length()) - (cl - s.length());
		//PApplet.println("segpos: " + l);
		return s.getPosAt(pos);
	}
	public void setLastSegment(Segment lastSegment) {
		this.lastSegment = lastSegment;
	}
	public Segment getLastSegment() {
		return lastSegment;
	}

	
}
